package com.jacky.flutter_screen_recording;

import static com.jacky.flutter_screen_recording.AppUtils.type;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Build;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.PixelCopy;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import com.jacky.log.Logger;
import com.meituan.flutter_logan.*;

import com.jacky.crypto.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**/ class FloatView extends FrameLayout implements View.OnClickListener {

    private ScreenRecordService mService;
    private WindowManager wm;
    private View btnOPen, btnClose;
    private TextView timeView;
    private TextView numberView;
    private boolean drag;
    private int mScreenWidthCenter;
    private Bitmap bitmap;
    private View toastView;
    private TouchListener mTouchListener;

    /**/ List<EvidShotBean> mShotArray;

    public FloatView(ScreenRecordService service) {
        super(service);
        mService = service;
        initViews(service);
//        setAlpha(0.8f);

        wm = getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = buildWindowParams(Gravity.TOP | Gravity.LEFT, 200);
        wm.addView(this, params);
    }

    private void initViews(Context context) {
        mTouchListener = new TouchListener();
        mShotArray = new ArrayList<>();
        LayoutInflater.from(context).inflate(R.layout.float_view, this);
        btnOPen = generateView(this, R.id.btn_open);
        btnClose = generateView(this, R.id.btn_close);
        generateView(this,  R.id.btn_shot);
        generateView(this,  R.id.btn_finish);
        generateView(this,  R.id.btn_shot_manager);
        timeView = this.findViewById(R.id.tvTime);
        numberView = this.findViewById(R.id.tv_number);
        TextView modeView = this.findViewById(R.id.tvMode);
        combine(false);

        drag = false;
        setKeepScreenOn(true);
        mScreenWidthCenter = getResources().getDisplayMetrics().widthPixels >> 1;
        modeView.setText(mService.mMicMode == 1 ? "外放" : "静音");

        this.setOnTouchListener(mTouchListener);
    }

    void removeFloatView() {
        if(wm != null) wm.removeView(this);
    }

    /**移除截图*/
    boolean removeShot(File shot){
        if(mShotArray == null || mShotArray.size() == 0 || shot == null) return false;
        int size = mShotArray.size();
        for (int i = 0 ; i < size ; i++) {
            EvidShotBean item = mShotArray.get(i);
            if(TextUtils.equals(item.fileName,shot.getName())){
                mShotArray.remove(i);
                shot.delete();
                updateShotManager(false);
                mService.onTakeShotOk(mShotArray.size());
                return true;
            }
        }
        return false;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        wm = getSystemService(Context.WINDOW_SERVICE);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        wm = null;
    }

    private <T> T getSystemService(String string) {
        return (T)getContext().getSystemService(string);
    }

    @Override
    public void onClick(final View v) {
        if(drag) return;
        int viewId = v.getId();
        if(viewId == R.id.btn_open){
            combine(true);
        }else if(viewId == R.id.btn_close){
            combine(false);
        }else if(viewId == R.id.btn_finish) {
            AppUtils.moveToFont(mService);
            getContext().sendBroadcast(new Intent(ShotManagerActivity.SCREEN_END_ACTION));
        } else if(viewId == R.id.btn_shot_manager) {
            ShotManagerActivity.start(getContext(), mService.mVideoPath);
        }else if(viewId == R.id.btn_shot){
            if(mShotArray.size() >= 1000) {
                Toast.makeText(mService, "当前图片数量太多，不允许继续截图", Toast.LENGTH_SHORT).show();
                return;
            }
            FloatView.this.setAlpha(0.8f);
            combine(false);
            v.setEnabled(false);
            FloatView.this.postDelayed(new Runnable() {
                @Override
                public void run() {
                    takeScreenImage(false);
                    FloatView.this.setAlpha(1);
                    combine(true);
                    v.setEnabled(true);
                }
            }, 1000);
        }
    }

    private void takeScreenImage(boolean auto) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            try {
                takeCurScreenImage(false);
            } catch (Exception e) {
                FlutterLoganPlugin.w("ScreenImage Error: " + e.getMessage(), 3);
            }
        }
    }

    private void saveBitmap(Bitmap bitmap, boolean auto) {
        if(bitmap == null) {
            showAlertToast("截图失败");
            return;
        }

        long time = System.currentTimeMillis();
        File file = mService.getSaveBitmapFile(time);

        AppUtils.saveBitmap(file, bitmap, Bitmap.CompressFormat.JPEG, 80);

        //存储图片的相关信息
        EvidShotBean element = new EvidShotBean();
        element.fileName  = file.getName();
        if("SHA-256".equals(mService.digest)) {
            element.md5 = EDA.SHA256.digest(file);
        } else {
            element.md5 = EDA.MD5.digest(file);
        }
        element.time = time;
        element.fileSize = file.length();
        element.filePath = file.getPath();
        mShotArray.add(element);

        mService.onTakeShotOk(mShotArray.size());
        if(element.fileSize > 30_000) {
            showAlertToast("截图成功");
        } else {
            showAlertToast("截图可能是黑屏");
        }
        updateShotManager(true);
    }

    /**更新截图数量内容*/
    private void updateShotManager(boolean sendBroadcast){
        if(numberView == null) return;
        if(mShotArray.size() == 0){
            numberView.setText("0");
            numberView.setVisibility(GONE);
        } else {
            numberView.setVisibility(VISIBLE);
            numberView.setText(String.valueOf(mShotArray.size()));
        }
        if(sendBroadcast) {
            getContext().sendBroadcast(new Intent(ShotManagerActivity.SHOT_ACTION));
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void takeCurScreenImage(boolean low) {
        if(mService.videoDisplay == null) return;
        if(bitmap == null) {
            Point point = new Point();
            mService.videoDisplay.getDisplay().getSize(point);
            bitmap = Bitmap.createBitmap(point.x, point.y, Bitmap.Config.ARGB_8888);
        }
        PixelCopy.request(mService.videoDisplay.getSurface(), bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
            @Override
            public void onPixelCopyFinished(int copyResult) {
                if (copyResult == PixelCopy.SUCCESS) {
                    Logger.d("Pixel copy success");
                    saveBitmap(bitmap, false);
                } else {
                    saveBitmap(null, false);
                    FlutterLoganPlugin.w("Failed to copy pixels from videoDisplay, result code: " + copyResult, 3);
                }
            }
        }, mService.mHandler);
    }

    public void updateTime(String time) {
        if(timeView != null) timeView.setText(time);
    }

    private WindowManager.LayoutParams buildWindowParams(int gravity, int offsetY) {
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.type = type();
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        params.format = PixelFormat.TRANSLUCENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = gravity;
        params.x = 0;
        params.y = offsetY;
        return params;
    }

    private View generateView(View group, int id) {
        View view = group.findViewById(id);
        view.setOnClickListener(this);
        view.setOnTouchListener(mTouchListener);
        return view;
    }

    private void combine(boolean open) {
        btnOPen.setVisibility(open ? GONE : VISIBLE);
        btnClose.setVisibility(open ? VISIBLE : GONE);
    }

    private class TouchListener implements OnTouchListener {
        private float lastY, lastX, firstY, firstX;
        private long time;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    drag = true;
                    time = System.currentTimeMillis();
                    firstY = lastY = event.getRawY();
                    firstX = lastX = event.getRawX();
                } break;
                case MotionEvent.ACTION_MOVE: move(event, false); break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    move(event, true);
                    break;
            }
            return false;
        }

        private void move(MotionEvent event, boolean isUp) {
            int x = (int) (event.getRawX());
            int y = (int) (event.getRawY());
            WindowManager.LayoutParams params = (WindowManager.LayoutParams) getLayoutParams();
            if(isUp) {
                params.x = x > mScreenWidthCenter ? (mScreenWidthCenter << 1) : 0;
                if(Math.abs(x - firstX) < 20 && Math.abs(y -firstY) < 20) {
                    if(System.currentTimeMillis() - time < 500) drag = false;//单次点击
                }
            } else {
                params.x += (int) (x - lastX);
                lastX = x;
            }
            params.y += (int) (y - lastY);
            lastY = y;
            wm.updateViewLayout(FloatView.this, params);
        }
    } //end TouchListener

    private void showAlertToast(String string) {
        showToast(getContext(), string);
    }

    private boolean showToast(Context context, String string) {
        final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.type = type();
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        params.format = PixelFormat.TRANSLUCENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = Gravity.CENTER;

        if(toastView == null) {
            toastView = LayoutInflater.from(context).inflate(R.layout.float_view_toast, null);
        }
        ((TextView)toastView).setText(string);
        toastView.postDelayed(new Runnable() {
            @Override
            public void run() {
                wm.removeView(toastView);
            }
        }, 800);
        try {
            wm.addView(toastView, params);
        } catch (Exception e) {
            Logger.w(e);
            return false;
        }
        return true;
    }
}//end float-view
